package com.tianquan.Transactional;/**
 * @author starsea
 * @date 2024-10-03 下午9:18
 */

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.SpringTransactionAnnotationParser;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAttribute;

/**
 * @BelongsProject: uploaddemo
 * @BelongsPackage: com.tianquan.redis
 * @Author: tianquan
 * @CreateTime: 2024-10-03  21:18
 * @Description: 事务管理器
 * @Version: 1.0
 */
@Component
public final class TransactionalManager implements ApplicationContextAware {

    private static PlatformTransactionManager platformTransactionManager;

    /**
     * 这里是spring提供的事务对象解析器,可以将注解对象转换成事务属性对象
     */
    private static final SpringTransactionAnnotationParser PARSER = new SpringTransactionAnnotationParser();

    /**
     * 开启事务 这里是对不组合 @Transactional注解 的实现
     */
    public static TransactionStatus begin() {
        return platformTransactionManager.getTransaction(TransactionDefinition.withDefaults());
    }

    /**
     * 接收一个 @Transactional 注解对象来开启事务
     */
    public static TransactionStatus begin(Transactional transactional) {
        TransactionAttribute transactionAttribute = PARSER.parseTransactionAnnotation(transactional);
        return platformTransactionManager.getTransaction(transactionAttribute);
    }

    /**
     * 提交事务
     */
    public static void commit(TransactionStatus status) {
        platformTransactionManager.commit(status);
    }

    /**
     * 关闭事务
     */
    public static void rollback(TransactionStatus status) {
        platformTransactionManager.rollback(status);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        platformTransactionManager = applicationContext.getBean(PlatformTransactionManager.class);
    }

}

